// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once
#include <cantor/parser/ast/base.h>
#include <cantor/parser/ast/expr.h>

namespace cantor::parser {
    static const char *for_lock_str[] = {"", " FOR UPDATE", " IN SHARED MODE"};


    struct DmlNode : public DefiniteExpr {
        DmlNode(cantor::pb::ast::ExprNodeType t,
                cantor::pb::ast::ExprNodeClass c) : DefiniteExpr(
            t, static_cast<cantor::pb::ast::ExprNodeClass>(c | cantor::pb::ast::ENC_DML)) {
        }

        DmlNode(cantor::pb::ast::ExprNodeType t) : DefiniteExpr(
           t, cantor::pb::ast::ENC_DML) {
        }

        nlohmann::ordered_json to_json_impl() const override;
    };

    class ColumnName;

    struct Assignment : public DmlNode {
        ColumnName *name = nullptr;
        DispatchExpr *expr = nullptr;

        Assignment() : DmlNode(pb::ast::ENT_ASSIGNMENT) {
        }

        nlohmann::ordered_json to_json() const override;

        void to_stream(std::ostream &os) const override;
    };

    enum ShowType {
        SHOW_NONE,
        SHOW_ENGINES,
        SHOW_DATABASES,
        SHOW_TABLES,
        SHOW_TABLE_STATUS,
        SHOW_COLUMNS,
        SHOW_WARNINGS,
        SHOW_CHARSET,
        SHOW_VARIABLES,
        SHOW_STATUS,
        SHOW_COLLATION,
        SHOW_CREATE_TABLE,
        SHOW_CREATE_VIEW,
        SHOW_GTRANTS,
        SHOW_TRIGGERS,
        SHOW_PROCEDURE_STATUS,
        SHOW_INDEX,
        SHOW_PROCESS_LIST,
        SHOW_CREATE_DATABASE,
        SHOW_EVNETS,
        SHOW_PLUGINS,
        SHOW_PROFILES,
        SHOW_PRIVILEGES,
        SHOW_MASTER_STATUS
    };

    class TableName;
    class ColumnName;
    struct ShowStmt : public DmlNode {
        ShowType show_type;
        String db_name;
        TableName *table_name = nullptr;
        ColumnName *column_name = nullptr;
        bool is_full = false;
        bool is_global = false;
        DispatchExpr *where = nullptr;
    };


    struct FieldItem : public DmlNode {
        FieldItem() : DmlNode(pb::ast::ENT_FIELD_ITEM) {
            value = nullptr;
        }

        nlohmann::ordered_json to_json() const override;

        pb::ast::LoadFieldType type = pb::ast::LOAD_TERMINATED;
        String value;
        bool opt_enclosed = false;
    };

    struct LinesClause : public DmlNode {
        LinesClause() : DmlNode(pb::ast::ENT_LINE_CLAUSE) {
            starting = nullptr;
            terminated = nullptr;
        }

        nlohmann::ordered_json to_json() const override;

        String starting;
        String terminated;
    };

    struct FieldsClause : public DmlNode {
        FieldsClause() : DmlNode(pb::ast::ENT_FIELD_CLAUSE) {
            terminated = nullptr;
            enclosed = nullptr;
            escaped = nullptr;
        }

        nlohmann::ordered_json to_json() const override;

        String terminated;
        String enclosed;
        String escaped;
        bool opt_enclosed = false;
    };
} // namespace cantor::parser
